package com.example.framework.util;

import java.util.Locale;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import com.example.framework.R;
import com.example.framework.base.CustomApplication;
import com.example.framework.interfaces.AsyncTaskInterface.*;

import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.Toast;

/**
 * Utility Class Of AsyncTask Used To Send Post Request By Asynchronous Mode.
 * 
 * @author renxin.sun
 * 
 */
public class UtilOfAsyncTask
{
	/**
	 * Used to doPostAsync method.
	 */
	public static String Url;
	public static String Params;

	/**
	 * 
	 * @param pCallEarliest
	 * @param pCallable
	 * @param pCallback
	 */
	@Deprecated
	public static <T> void doAsync(final CallEarliest<T> callEarliest, final Callable<T> callable, final Callback<T> callback)
	{
		new AsyncTask<Void, Void, T>()
		{
			/**
			 * Run in the main thread.
			 */
			@Override
			protected void onPreExecute()
			{
				super.onPreExecute();
				try
				{
					callEarliest.onCallEarliest();
				}
				catch (Exception e)
				{
					Log.e("error", e.toString());
				}
			}

			/**
			 * Run in the another thread!!!
			 */
			@Override
			protected T doInBackground(Void... params)
			{
				try
				{
					return callable.call();
				}
				catch (Exception e)
				{
					Log.e("error", e.toString());
				}

				return null;
			}

			/**
			 * Run in the main thread.
			 */
			protected void onPostExecute(T result)
			{
				callback.onCallback(result);
			}

		}.execute((Void[]) null);
	}

	/**
	 * 
	 * @param pContext
	 * @param styleID
	 * @param pTitle
	 * @param pMessage
	 * @param pCallEarliest
	 * @param progressCallable
	 * @param pCallback
	 */
	@Deprecated
	public static <T> void doProgressAsync(final Context context, final int styleID, final String pTitle, final String pMessage, final CallEarliest<T> callEarliest, final ProgressCallable<T> progressCallable, final Callback<T> callback)
	{

		new AsyncTask<Void, Void, T>()
		{
			private ProgressDialog mProgressDialog;

			@Override
			protected void onPreExecute()
			{
				super.onPreExecute();

				mProgressDialog = new ProgressDialog(context);
				mProgressDialog.setProgressStyle(styleID);
				mProgressDialog.setTitle(pTitle);
				mProgressDialog.setMessage(pMessage);
				mProgressDialog.setIndeterminate(false);
				mProgressDialog.show();

				try
				{
					callEarliest.onCallEarliest();
				}
				catch (Exception e)
				{
					Log.e("error", e.toString());
				}
			}

			@Override
			protected T doInBackground(Void... params)
			{
				try
				{
					return progressCallable.call(new ProgressListener()
					{
						@Override
						public void onProgressChanged(int progress)
						{
							onProgressUpdate(progress);
						}
					});
				}
				catch (Exception e)
				{
					Log.e("error", e.toString());
				}

				return null;
			}

			protected void onProgressUpdate(final Integer... values)
			{
				mProgressDialog.setProgress(values[0]);
			};

			protected void onPostExecute(T result)
			{
				if (mProgressDialog != null)
					mProgressDialog.dismiss();
				callback.onCallback(result);
			}

		}.execute((Void[]) null);

	}

	/**
	 * 
	 * @param pContext
	 * @param styleID
	 * @param pTitleResId
	 * @param pMessageResId
	 * @param pCallEarliest
	 * @param progressCallable
	 * @param pCallback
	 */
	@Deprecated
	public static <T> void doProgressAsync(final Context context, final int styleID, final int titleResId, final int messageResId, final CallEarliest<T> callEarliest, final ProgressCallable<T> progressCallable, final Callback<T> callback)
	{
		UtilOfAsyncTask.doProgressAsync(context, styleID, context.getString(titleResId), context.getString(messageResId), callEarliest, progressCallable, callback);
	}

	/**
	 * Send post request to access server and get the response.
	 * 
	 * @param <T>
	 * 
	 * @param context
	 * @param onPreCall
	 * @param onCallBack
	 */
	public static void doPostAsync(final Context context, final Dialog progressDialog, final OnPreCall onPreCall, final OnCallBack onCallBack)
	{
		if(!Util.isConnectedNetwork(context))
		{
			Toast.makeText(context, R.string.nonetwork, Toast.LENGTH_SHORT).show();
			return;
		}
		new AsyncTask<Void, Void, String>()
		{
			@Override
			protected void onPreExecute()
			{
				super.onPreExecute();

				UtilOfDialog.showProgressDialog(context, progressDialog);

				try
				{
					onPreCall.SetUrlAndParams(new PreCallListener()
					{
						@Override
						public void SetUrl(String url)
						{
							Url = url;
						}

						@Override
						public void SetParams(String params)
						{
							Params = params;
						}

					});
				}
				catch (Exception e)
				{
					Log.e("error", e.toString());
				}
			}

			@Override
			protected String doInBackground(Void... params)
			{
				String response = "";
				HttpClient httpclient = new DefaultHttpClient();

				HttpPost httppost = new HttpPost(UtilOfAsyncTask.Url);
				try
				{
					httppost.setEntity(new StringEntity(UtilOfAsyncTask.Params, HTTP.UTF_8));

					Log.i(CustomApplication.ASYNC_TAG, "PostUrl:\r\n" + UtilOfAsyncTask.Url);
					Log.i(CustomApplication.ASYNC_TAG, "PostParams:\r\n" + UtilOfAsyncTask.Params);

					httpclient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, 5000);
					httpclient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, 5000);

					HttpResponse httpResponse;
					httpResponse = httpclient.execute(httppost);

					int statusCode = httpResponse.getStatusLine().getStatusCode();
					Log.i(CustomApplication.ASYNC_TAG, "HttpStatus:\r\n" + "" + statusCode);

					if (statusCode == HttpStatus.SC_OK)
					{
						response = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8);
					}
					else
					{
						response = "";
					}
				}
				catch (Exception e)
				{
					Log.i(CustomApplication.ASYNC_TAG, "HttpException:\r\n" + "" + e.toString());
					return "";
				}

				Log.i(CustomApplication.ASYNC_TAG, "PostResponse:\r\n" + response);

				return response;
			}

			protected void onPostExecute(String result)
			{
				UtilOfDialog.dismissProgressDialog(progressDialog);

				if (result.toLowerCase(Locale.getDefault()).contains("errorcode"))
				{
					Toast.makeText(context, R.string.requestparams_incomplete, Toast.LENGTH_SHORT).show();
					onCallBack.OnError();
				}
				else if (!"".equals(result) && !result.toLowerCase(Locale.getDefault()).contains("errorcode"))
				{
					onCallBack.OnSuccess(result);
				}
				else
				{
					Toast.makeText(context, R.string.requestserver_error, Toast.LENGTH_SHORT).show();
				}
			}

		}.execute((Void[]) null);

	}

}
